﻿using System;
using System.Collections.Generic;
using GDGeek;
using UnityEngine;

namespace MrPP.SerriedCabinet
{

    [System.Serializable]
    public class CabinetGroup: GDGeek.Singleton<CabinetGroup>
    {
        [SerializeField]
        private bool _update = false;
        public void Update() {
           // this.longName().GetHashCode();
            if (_update) {
                this.onChange?.Invoke();
                _update = false;
            }
        }
        [SerializeField]
        private Setup _setup;

        public int fix
        {
            get
            {
                return data.cabinets.fix;
            }

        }

        [System.Serializable]
        public struct ItemData
        {

            public string text;
            public BoxLocation location;

            public int target;
            public string sn;

            public Box.Type type {
                set {
                    location.type = value;
                }
                
                get{
                    return location.type;
                }
            
            }

            public int box
            {
                set
                {
                    location.box = value;
                }

                get
                {
                    return location.box;
                }

            }
            public int sile
            {
                set
                {
                    location.sile = value;
                }

                get
                {
                    return location.sile;
                }

            }
            public int layer
            {
                set
                {
                    location.layer = value;
                }

                get
                {
                    return location.layer;  
                }
            }
            public Vector2Int position
            {
                set
                {
                    sile = value.x;
                    layer = value.y;
                }
                get
                {
                    return new Vector2Int(sile, layer);
                }
            }
        }


        public ItemData getItem(ArchivesData arch)
        {
            for (int i = 0; i < this._setup.data.cabinets.item.Length; ++i) {
                var it = this._setup.data.cabinets.item[i];
                if (it.area == arch.area && it.index == arch.column)
                {
                    ItemData ret = new ItemData();
                    ret.box = i;

                    ret.text = arch.doc_name;
                    ret.sn = arch.sn;
                    ret.layer = arch.layer;

                    if (arch.section < it.left.Length)
                    {
                        ret.type = Box.Type.Left;
                        ret.position = new Vector2Int(arch.section, arch.layer);
                        if (ret.box == data.cabinets.fix)
                        {
                            ret.target = ret.box -1;
                        }
                        else if (ret.box < data.cabinets.fix)
                        {
                            
                            ret.target = ret.box - 1;
                           
                        }
                        else
                        {
                            ret.target = ret.box;
                        }


                    }
                    else {

                        ret.type = Box.Type.Right;
                        ret.position = new Vector2Int(arch.section- it.left.Length, arch.layer);

                        if (ret.box == data.cabinets.fix)
                        {
                            //Debug.LogError("0data.column" + ret.box + "|" + data.cabinets.fix);
                            ret.target = ret.box + 1;
                        }
                        else if (ret.box < data.cabinets.fix)
                        {
                           // Debug.LogError("data.column" + ret.box + "|" + data.cabinets.fix);
                            ret.target = ret.box;
                        }
                        else
                        {
                          //  Debug.LogError("2data.column" + ret.box + "|" + data.cabinets.fix);
                            ret.target = ret.box + 1;
                           
                        }
                    }
                    if (ret.target >= this.count || ret.target < 0)
                    {
                        ret.target = -1;
                    }
                    return ret;
                }
            }
            
            var id = new ItemData();
            id.type = Box.Type.None;
            return id;
          
        }

        public float getTemperature()
        {
            return (float)(data.temperature) / 10f;
        }
        public float getHumidity()
        {

            return (float)(data.humidity);
        }

     

       
        void Start()
        {
           InitialStatusFactory.Instance.onRecevie += setup;
            ActiveColumnPositionsFactory.Instance.onRecevie += setup;
            ActiveColumnStatusFactory.Instance.onRecevie += setup;
          //  AreaColumnConfigurationFactory.Instance.onRecevie += setup;
        }

        void OnDestroy()
        {
           // if (AreaColumnConfigurationFactory.IsInitialized) {
           //     AreaColumnConfigurationFactory.Instance.onRecevie -= setup;
           // }
            if (InitialStatusFactory.IsInitialized)
            {
                InitialStatusFactory.Instance.onRecevie -= setup;
            }
            if (ActiveColumnPositionsFactory.IsInitialized)
            {
                ActiveColumnPositionsFactory.Instance.onRecevie -= setup;
            }
            if (ActiveColumnStatusFactory.IsInitialized)
            {
                ActiveColumnStatusFactory.Instance.onRecevie -= setup;
            }

        }

        public Action onSetup
        {
            get
            {
                return _setup.onSetup;
            }
            set
            {
                _setup.onSetup = value;
            }
        }


        public Action onChange {
            get;
            set;
        }


        [SerializeField]
        private List<int> positions_ = null;
        [SerializeField]
        private List<int> status_ = null;
        private List<int> status
        {
            get
            {
                if (status_ == null || status_.Count != this.count)
                {
                    status_ = new List<int>();
                    for (int i = 0; i < this.count; ++i)
                    {
                        status_.Add(0);
                    }

                }
                return status_;
            }

        }
       
        private List<int> positions
        {
            get
            {
                if (positions_ == null || positions_.Count != this.count)
                {
                    positions_ = new List<int>();
                    for (int i = 0; i < this.count; ++i) {
                        positions_.Add(0);
                    }


                }
                return positions_;
            }

        }

        
        public CabinetItem getItem(int index)
        {
            CabinetItem item = new CabinetItem();
            item.item = data.cabinets.item[index];
            item.position = this.positions[index];
            item.status = this.status[index]; /* */
            return item;
        }
        public int count
        {
            get
            {
                return data.cabinets.item.Length;
            }
        }
        public Setup.Data data
        {
            get
            {
                return _setup.data;
            }
            set {
                _setup.data = value;
            }
        }
       
        public bool initialized { get {

                return _setup._init;
            }
        
        }
        /*
        public void setup(AreaColumnConfigurationFactory.Data data) {
          //  set
            onChange?.Invoke();
        }*/
        public void setup(ActiveColumnPositionsFactory.Data data)
        {
            setPositions(data.area, data.positions);
            onChange?.Invoke();
        }

        public void setup(ActiveColumnStatusFactory.Data data)
        {
            setStatus(data.area, data.status);
            onChange?.Invoke();

        }
        public void setup(InitialStatusFactory.Data data)
        {
        //    Debug.LogError("!!!!!!!????====" + JsonUtility.ToJson(data));
            foreach (var d in data.areas) {
               setStatus(d.area, d.status);
               setPositions(d.area, d.positions);
            }

            onChange?.Invoke();
        }


        public void setStatus(int area, int[] status)
        {


            var items = CabinetGroup.Instance.data.cabinets.item;


            int n = 0;
            for (int i = 0; i < items.Length; ++i)
            {
                if (IsFixed(items[i]) || items[i].area != area)
                {
                    continue;
                }

                this.status[i] = status[n];
                n++;

            }


        }

        public static bool IsFixed(Box.Data item)
        {
           return (item.type == 2 ||item.type == 3 || item.type == 4);
        }
        public void setPositions(int area, int[] positions)
        {
            
            var items = CabinetGroup.Instance.data.cabinets.item;

            int n = 0;
            for (int i = 0; i < items.Length; ++i)
            {

                if (IsFixed(items[i]) || items[i].area != area)
                {
                    continue;
                }

                if (i >= this.positions.Count || n >= positions.Length) {
                    continue;
                }
                this.positions[i] = positions[n];
                n++;

            }


        }
    }
}